package com.teamsun.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.teamsun.entity.TableHeader;
import com.teamsun.rptcfg.BaseRpt;
import com.teamsun.rptcfg.BaseRptColumn;
import com.teamsun.rptcfg.RptDrill;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.List;
import java.util.Map;

/**
 * <p>报表配置相关公共类</p>
 */
public class RptCfgUtils {

    /**
     * <p>根据Excle表头信息生成报表配置模板</p>
     * @param excelHeaderJson 表头信息JSON字符串
     * @param rptName 报表名称
     * @return
     */
    public static Document createRptXMLFile(String excelHeaderJson, String rptName) {
        // 将JSON字符串转换成TableHeader对象
        List<List<TableHeader>> headers = JSON.parseObject(excelHeaderJson, new TypeReference<List<List<TableHeader>>>(){});

        // 根据解析的JSON,生成报表模板配置文件
        Document document = DocumentHelper.createDocument();
        // 生成根节点
        Element report = document.addElement("report");
        report.addAttribute("name", rptName);  // 报表名称属性

        // 生成根节点下的column节点
        for(int i=0; i<headers.size(); i++) {
            List<TableHeader> headerList = headers.get(i);
            for(TableHeader header : headerList) {
                int colSpan = header.getColspan();
                if(colSpan == 0) {
                    Element column = report.addElement("column");
                    column.addAttribute("name", header.getTitle());
                    column.addAttribute("field", "");
                    column.addAttribute("aliasField", "");
                    column.addAttribute("colType", "");
                }
            }
        }

        // 生成from节点
        Element from = report.addElement("from");
        from.setText("");

        // 生成order节点
        Element order = report.addElement("order");
        order.setText("");

        // 生成group节点
        Element group = report.addElement("group");
        group.setText("");

        return document;
    }

    /**
     * 重置报表表头信息(解析完报表配置文件后,需要将报表表头中的field、align、width字段赋值)
     * @param excelHeaderJson 表头JSON字符串
     * @param baseRpt 报表对象
     * @return
     */
    public static List<List<TableHeader>> resetRptHeader(String excelHeaderJson, BaseRpt baseRpt) {
        // 将JSON字符串转换成TableHeader对象
        List<List<TableHeader>> headers = JSON.parseObject(excelHeaderJson, new TypeReference<List<List<TableHeader>>>(){});

        // 获取报表配置的显示列信息
        List<BaseRptColumn> rptColumns = baseRpt.getRptColumns();
        // 获取报表配置的隐藏列信息
        List<BaseRptColumn> hiddenRptColumns = baseRpt.getHiddenRptColumns();
        // 获取查询条件列
        List<BaseRptColumn> conditionColumns = baseRpt.getConditionColumns();

        // 默认列宽(如果列宽未配置)
        int defaultWidth = 0;
        if(Constants.YES.equals(baseRpt.getNeedAnalysis())) {
            defaultWidth = Constants.RPT_ANALYSIS_DEFAULT_WIDTH / rptColumns.size();
        } else {
            defaultWidth = Constants.RPT_DEFAULT_WIDTH / rptColumns.size();
        }

        int colCount = 0;
        boolean hiddenFlag = true;
        String dynamic = "";
        for(int i=0; i<headers.size(); i++) {
            List<TableHeader> headerList = headers.get(i);
            for(TableHeader header : headerList) {
                int colSpan = header.getColspan();
                if(colSpan == 0) {  // colSpan为0则表示该列为配置列
                    BaseRptColumn rptColumn = rptColumns.get(colCount);
                    String width = rptColumn.getWidth();  // 列宽
                    String align = rptColumn.getAlign();  // 列对齐方式
                    String field = rptColumn.getAliasField();  // 列field
                    String isDrill = rptColumn.getIsDrill();  // 列是否下钻
                    String numberFomat = rptColumn.getNumberFormat();  // 数字格式化方式
                    String dynamicFormat = rptColumn.getDynamicFormat();  // 动态配置的数字格式化方式
                    String fontColorByValue = rptColumn.getFontColorByValue();  // 通过和指定值比较，设置字体颜色
                    String fontColorByRow = rptColumn.getFontColorByRow();  // 通过和指定列的比较，设置字体的颜色
                    String fontColorByRange = rptColumn.getFontColorByRange();  // 和指定值区间比较，设置字体颜色
                    String colType = rptColumn.getColType();
                    String isSort = rptColumn.getIsSort();
                    String conditionType = rptColumn.getConditionType();
                    String unit = rptColumn.getUnit();  // 列单位
                    String title = header.getTitle();  // 表头名称
                    String aliasTitle = rptColumn.getName();

                    header.setAliasTitle(aliasTitle);
                    if(StringUtils.isNotBlank(unit)) {
                        header.setUnit(unit);
                    } else {
                        header.setUnit("");
                    }
                    header.setField(field);
                    if(Constants.YES.equals(isSort)) {
                        header.setSortable(true);
                    } else {
                        header.setSortable(false);
                    }
                    if(Constants.COL_TYPE_HID_DIM.equals(colType) || Constants.COL_TYPE_HID_IDX.equals(colType)) {
                        header.setHidden(true);
                    } else {
                        header.setHidden(false);
                    }
                    if(StringUtils.isNotBlank(width)) {  // 设置列宽度
                        header.setWidth(Integer.valueOf(width));
                    } else {
                        header.setWidth(defaultWidth);
                    }
                    if(StringUtils.isNotBlank(align)) {  // 设置列对齐方式
                        header.setAlign(align);
                    }

                    String formatter = "";
                    // 和指定的值比较，设置字体颜色
                    if(StringUtils.isNotBlank(fontColorByValue)) {
                        String[] cfgs = fontColorByValue.split(",");
                        String compareValue = cfgs[0];  // 待比较的值
                        String lessColor = cfgs[1];  // 小于比较值时，字体的颜色
                        String greatColor = "";  // 大于比较值是，字体的颜色
                        if(cfgs.length == 3) {
                            greatColor = cfgs[2];
                        }
                        formatter = "function(value,row,index){return fontColorByValue('" + compareValue + "','" + lessColor + "','" + greatColor + "',value,row,index)}";
                        header.setFormatter(formatter);
                    } else {
                        if(StringUtils.isBlank(formatter)) {
                            header.setFormatter("");
                        }
                    }

                    // 和指定的列值比较，设置字体颜色
                    if(StringUtils.isNotBlank(fontColorByRow)) {
                        String[] cfgs = fontColorByRow.split(",");
                        String compareRow = cfgs[0];  // 待比较的列
                        String lessColor = cfgs[1];  // 小于比较值时，字体的颜色
                        String greatColor = "";  // 大于比较值是，字体的颜色
                        if(cfgs.length == 3) {
                            greatColor = cfgs[2];
                        }
                        formatter = "function(value,row,index){return fontColorByRow('" + compareRow + "','" + lessColor + "','" + greatColor + "',value,row,index)}";
                        header.setFormatter(formatter);
                    } else {
                        if(StringUtils.isBlank(formatter)) {
                            header.setFormatter("");
                        }
                    }

                    // 和指定的值区间比较，设置字体颜色
                    if(StringUtils.isNotBlank(fontColorByRange)) {
                        String[] cfgs = fontColorByRange.split(",");
                        String startValue = cfgs[0];  // 起始值
                        String endValue = cfgs[1];  // 结束值
                        String lessColor = cfgs[2];  // 小于比较值时，字体的颜色
                        String rangeColor = cfgs[3];  // 值区间内时，字体的颜色
                        String greatColor = "";  // 大于比较值是，字体的颜色
                        if(cfgs.length == 5) {
                            greatColor = cfgs[4];
                        }
                        formatter = "function(value,row,index){return fontColorByRange('" + startValue + "','" + endValue + "','" + lessColor + "','" + rangeColor + "','" + greatColor + "',value,row,index)}";
                        header.setFormatter(formatter);
                    } else {
                        if(StringUtils.isBlank(formatter)) {
                            header.setFormatter("");
                        }
                    }

                    if(Constants.YES.equals(isDrill)) {  // 设置列下钻信息
                        RptDrill rptDrill = rptColumn.getRptDrill();
                        String rptId = rptDrill.getRptId();  // 下钻报表ID
                        String drillParam = rptDrill.getParam();  // 下钻参数
                        if(StringUtils.isBlank(drillParam)) {
                            drillParam = "";
                        }
                        String conditionParam = rptDrill.getConditionParam();  // 条件参数
                        if(StringUtils.isBlank(conditionParam)) {
                            conditionParam = "";
                        }
                        String drillLayout = rptDrill.getDrillLayout();  // 下钻方式(新页面打开或当期页面打开)
                        String needSum = baseRpt.getNeedSum();  // 报表是否需要汇总
                        String defaultSum = baseRpt.getDefaultSum();
                        if(Constants.YES.equals(defaultSum)) {
                            needSum = Constants.YES;
                        }
                        // 获取表格第一列
                        String firstCol = rptColumns.get(0).getAliasField();
                        //String formatter = "rptDrill(\"" + rptId + "\",\"" + drillParam + "\")";
                        formatter = "function(value,row,index){return rptDrill('" + rptId + "','" + drillParam + "','" + conditionParam + "','" + firstCol + "','" + needSum + "',value,row,index)}";
                        //String formatter = "rptDrill";
                        header.setFormatter(formatter);
                    } else {
                        if(StringUtils.isBlank(formatter)) {
                            header.setFormatter("");
                        }
                    }

                    if(StringUtils.isNotBlank(numberFomat)) { // 设置数字的格式化方式
                        header.setDynamicFormatter(false);

                        formatter = "function(value,row,index){return numberFormat('" + numberFomat + "',value,row,index)}";
                        if(StringUtils.isNotBlank(fontColorByValue)) {
                            String[] cfgs = fontColorByValue.split(",");
                            String compareValue = cfgs[0];  // 待比较的值
                            String lessColor = cfgs[1];  // 小于比较值时，字体的颜色
                            String greatColor = "";  // 大于比较值是，字体的颜色
                            if(cfgs.length == 3) {
                                greatColor = cfgs[2];
                            }
                            formatter = "function(value,row,index){return formatColorByValue('" + compareValue + "','" + lessColor + "','" + greatColor + "','" + numberFomat + "',value,row,index)}";
                        } else if(StringUtils.isNotBlank(fontColorByRow)) {
                            String[] cfgs = fontColorByRow.split(",");
                            String compareRow = cfgs[0];  // 待比较的值
                            String lessColor = cfgs[1];  // 小于比较值时，字体的颜色
                            String greatColor = "";  // 大于比较值是，字体的颜色
                            if(cfgs.length == 3) {
                                greatColor = cfgs[2];
                            }
                            formatter = "function(value,row,index){return formatColorByRow('" + compareRow + "','" + lessColor + "','" + greatColor + "','" + numberFomat + "',value,row,index)}";
                        } else if(StringUtils.isNotBlank(fontColorByRange)) {
                            String[] cfgs = fontColorByRange.split(",");
                            String startValue = cfgs[0];  // 起始值
                            String endValue = cfgs[1];  // 结束值
                            String lessColor = cfgs[2];  // 小于比较值时，字体的颜色
                            String rangeColor = cfgs[3];  // 值区间内时，字体的颜色
                            String greatColor = "";  // 大于比较值是，字体的颜色
                            if(cfgs.length == 5) {
                                greatColor = cfgs[4];
                            }
                            formatter = "function(value,row,index){return formatColorByRange('" + startValue + "','" + endValue + "','" + lessColor + "','" + rangeColor + "','" + greatColor + "','" + numberFomat + "',value,row,index)}";
                        }

                        header.setFormatter(formatter);

                        title = resetHeaderTitle(numberFomat, unit, aliasTitle);
                        header.setTitle(title);
                    } else if(StringUtils.isNotBlank(dynamicFormat) && Constants.DYNAMICFORMAT_VALUE.equals(dynamicFormat)) {
                        header.setDynamicFormatter(true);

                        formatter = "function(value,row,index){return dynamicNumberFormat('" + dynamicFormat + "',value,row,index)}";
                        header.setFormatter(formatter);

                        // 如果报表列为动态格式化数字,则需要根据选择的计数方式动态重置表头名称(加单位)
                        if(StringUtils.isNotBlank(unit)) {
                            String numberFormat = "";
                            // 获取动态配置的数字格式化信息
                            for (BaseRptColumn conditionColumn : conditionColumns) {
                                String aliasField = conditionColumn.getAliasField();
                                if (aliasField.equals(dynamicFormat)) {
                                    Map<String, String> optionValue = conditionColumn.getOptionValue();
                                    if (optionValue != null && optionValue.size() > 0) {
                                        numberFormat = optionValue.entrySet().iterator().next().getKey();
                                        break;
                                    }
                                }
                            }

                            if(StringUtils.isNotBlank(numberFormat)) {
                                dynamic = numberFormat;
                            }
                            title = resetHeaderTitle(numberFormat, unit, aliasTitle);
                            header.setTitle(title);

                            String countType = getCountType(numberFormat);
                            rptColumn.setCountType(countType);
                        }
                    } else {
                        header.setDynamicFormatter(false);

                        // 如果配置单位，则需要为表头添加单位
                        if(StringUtils.isNotBlank(unit)) {
                            title = resetHeaderTitle(numberFomat, unit, aliasTitle);
                            header.setTitle(title);
                        }
                    }

                    if(StringUtils.isNotBlank(conditionType)) {  // 如果列是查询列，且是下拉框，则前台显示需要转义
                        if(Constants.CONDITIONTYPE_SELECT.equals(conditionType) || Constants.CONDITIONTYPE_MULTI_SELECT.equals(conditionType)) {
                            formatter = "function(value,row,index){return transInfo('" + field + "',value,row,index)}";
                            header.setFormatter(formatter);
                        } else {
                            if(StringUtils.isBlank(formatter)) {
                                header.setFormatter("");
                            }
                        }
                    }

                    // 如果报表配置文件中额外配置了隐藏列,将隐藏列信息添加到表头配置中
                    if(hiddenRptColumns != null && hiddenRptColumns.size() > 0 && hiddenFlag) {
                        for(BaseRptColumn hiddenColumn : hiddenRptColumns) {
                            TableHeader tableHeader = new TableHeader();
                            String hiddenField = hiddenColumn.getAliasField();  // 列field
                            tableHeader.setField(hiddenField);
                            tableHeader.setHidden(true);
                        }
                        hiddenFlag = false;
                    }
                    colCount ++;
                }
            }
        }

        // 设置条件列的属性
        if(StringUtils.isNotBlank(dynamic)) {
            for (BaseRptColumn rptColumn : conditionColumns) {
                String dynamicFormat = rptColumn.getDynamicFormat();
                if(StringUtils.isNotBlank(dynamicFormat) && Constants.DYNAMICFORMAT_VALUE.equals(dynamicFormat)) {
                    String countType = getCountType(dynamic);
                    rptColumn.setCountType(countType);
                }
            }
        }

        return headers;
    }

    /**
     * 根据数字格式化信息重置表头名称
     * @param numberFomat 数字格式化信息
     * @param unit 列单位
     * @return
     */
    public static String resetHeaderTitle(String numberFomat, String unit, String title) {
        if(StringUtils.isNotBlank(numberFomat)) {
            if(numberFomat.indexOf(".") > 0) {
                int nodeLength = numberFomat.length() - 2;  // 获取小数位长度
                if(nodeLength == 1) {
                    unit = "十" + unit;
                } else if(nodeLength == 2) {
                    unit = "百" + unit;
                } else if(nodeLength == 3) {
                    unit = "千" + unit;
                } else if(nodeLength == 4) {
                    unit = "万" + unit;
                }
            }
        }

        if(StringUtils.isNotBlank(unit)) {
            title = title + "(" + unit + ")";
            /*if(!title.contains(unit)) {
                title = title + "(" + unit + ")";
            }*/
        }
        return title;
    }

    /**
     * 获取计数方式
     * @param numberFormatter
     * @return
     */
    public static String getCountType(String numberFormatter) {
        String countType = "";

        if(StringUtils.isNotBlank(numberFormatter)) {
            if(numberFormatter.indexOf(".") > 0) {
                int nodeLength = numberFormatter.length() - 2;  // 获取小数位长度
                if(nodeLength == 1) {
                    countType = "十";
                } else if(nodeLength == 2) {
                    countType = "百";
                } else if(nodeLength == 3) {
                    countType = "千";
                } else if(nodeLength == 4) {
                    countType = "万";
                }
            }
        }

        return countType;
    }
}
